import logging
from bilibili_api import live, Credential, user
import os
import sys
import importlib.util
CONFIG_API_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../tools/config_api.py'))
spec = importlib.util.spec_from_file_location("config_api", CONFIG_API_PATH)
config_api = importlib.util.module_from_spec(spec)
sys.modules["config_api"] = config_api
spec.loader.exec_module(config_api)

logger = logging.getLogger("bilibili.manager")

class LiveRoomManager:
    async def block_user(self, uid):
        """将用户拉黑（仅主号或有权限小号可用）"""
        if not self.user:
            logger.warning("未登录，无法拉黑用户")
            return False
        try:
            # 0分钟=永久拉黑
            await self.user.block_user_in_live_room(self.room_id, uid, 0)
            logger.info(f"已拉黑用户 {uid}")
            return True
        except Exception as e:
            logger.error(f"拉黑失败: {e}")
            return False
    def __init__(self, room_id):
        self.room_id = room_id
        self.credential = self._load_credential()
        self.room = live.LiveDanmaku(room_id, credential=self.credential) if self.credential else live.LiveDanmaku(room_id)
        self.user = None
        # 注意：请在实例化后调用 await manager.init_user() 进行异步初始化
        self.event_callbacks = {
            "WELCOME": [],
            "WELCOME_GUARD": [],
            "ENTRY_EFFECT": [],
            "DANMU_MSG": [],
        }

    async def get_user_room_info(self, uid: int) -> dict:
        """
        查询用户在直播间的详细身份信息（如房管、舰长、粉丝牌等），请求时带上cookie，增强异常处理。
        """
        import aiohttp
        config = config_api.get_config()
        anchor_uid = config.get('bilibili', {}).get('uid')
        if not anchor_uid:
            raise Exception('配置文件未设置主播uid(bilibili.uid)')
        url = f'https://api.live.bilibili.com/xlive/app-ucenter/v2/card/user?ruid={anchor_uid}&uid={uid}'
        cookies = config.get('bilibili', {}).get('cookie', {})
        jar = aiohttp.CookieJar()
        for k in ['SESSDATA', 'DedeUserID', 'bili_jct']:
            v = cookies.get(k)
            if v:
                jar.update_cookies({k: v})
        headers = {
            'User-Agent': 'Mozilla/5.0',
            'Referer': 'https://live.bilibili.com/'
        }
        async with aiohttp.ClientSession(cookie_jar=jar, headers=headers) as session:
            async with session.get(url, timeout=10) as resp:
                content_type = resp.headers.get('Content-Type', '')
                if 'application/json' in content_type:
                    data = await resp.json()
                    if data.get('code') == 0:
                        return data.get('data', {})
                    else:
                        raise Exception(f'查询失败: {data}')
                else:
                    text = await resp.text()
                    raise Exception(f'接口返回非JSON，可能未登录或被风控，content_type={content_type}, 响应内容片段: {text[:120]}')

    def _load_credential(self):
        config = config_api.get_config()
        cookies = config.get('bilibili', {}).get('cookie', {})
        sessdata = cookies.get('SESSDATA')
        bili_jct = cookies.get('bili_jct')
        dedeuserid = cookies.get('DedeUserID')
        if sessdata and bili_jct and dedeuserid:
            return Credential(sessdata, bili_jct, dedeuserid)
        return None

    async def init_user(self):
        """
        异步初始化用户信息。请在实例化后调用：await manager.init_user()
        """
        if self.credential:
            try:
                info = await user.get_self_info(self.credential)
                self.user = user.User(uid=info.get('mid'), credential=self.credential)
            except Exception as e:
                logger.warning(f"无法初始化用户: {e}")
    @classmethod
    async def create(cls, room_id):
        """
        推荐用法：manager = await LiveRoomManager.create(room_id)
        """
        self = cls(room_id)
        await self.init_user()
        return self

    def on(self, event_name, callback):
        if event_name in self.event_callbacks:
            self.event_callbacks[event_name].append(callback)
        else:
            self.event_callbacks[event_name] = [callback]

    async def start(self):
        @self.room.on("WELCOME")
        async def _on_welcome(event):
            for cb in self.event_callbacks.get("WELCOME", []):
                await cb(event)
        @self.room.on("WELCOME_GUARD")
        async def _on_welcome_guard(event):
            for cb in self.event_callbacks.get("WELCOME_GUARD", []):
                await cb(event)
        @self.room.on("ENTRY_EFFECT")
        async def _on_entry_effect(event):
            for cb in self.event_callbacks.get("ENTRY_EFFECT", []):
                await cb(event)
        @self.room.on("DANMU_MSG")
        async def _on_danmu(event):
            for cb in self.event_callbacks.get("DANMU_MSG", []):
                await cb(event)
        await self.room.connect()
        logger.info(f"直播间管理器已连接到房间 {self.room_id}")

    async def mute_user(self, uid, minute=5):
        if not self.user:
            logger.warning("未登录，无法禁言用户")
            return False
        try:
            await self.user.block_user_in_live_room(self.room_id, uid, minute)
            logger.info(f"已禁言用户 {uid} {minute} 分钟")
            return True
        except Exception as e:
            logger.error(f"禁言失败: {e}")
            return False

    async def kick_user(self, uid):
        if not self.user:
            logger.warning("未登录，无法踢出用户")
            return False
        try:
            await self.user.kick_user_from_live_room(self.room_id, uid)
            logger.info(f"已踢出用户 {uid}")
            return True
        except Exception as e:
            logger.error(f"踢人失败: {e}")
            return False
